{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "o4JZ84moBKMr"
   },
   "source": [
    "# Differentiable Fluid Simulations\n",
    "\n",
    "We now target a more complex example with the Navier-Stokes equations as physical model. In line with {doc}`overview-ns-forw`, we'll target a 2D case.\n",
    "\n",
    "As optimization objective we'll consider a more difficult variant of the previous Burgers example: the state of the observed density $s$ should match a given target after $n=20$ steps of simulation. In contrast to before, the observed quantity in the form of the marker field $s$ cannot be changed in any way. Only the initial state of the velocity $\\mathbf{u}_0$ at $t=0$ can be modified. This gives us a split between observable quantities for the loss formulation and quantities that we can interact with during the optimization (or later on via NNs).\n",
    "[[run in colab]](https://colab.research.google.com/github/tum-pbs/pbdl-book/blob/main/diffphys-code-ns.ipynb)\n",
    "\n",
    "## Physical Model\n",
    "\n",
    "We'll use an inviscid  Navier-Stokes model with velocity $\\mathbf{u}$, no explicit viscosity term, and a smoke marker density $s$ that drives a simple Boussinesq buoyancy term $\\eta d$ adding a force along the y dimension. Due to a lack of an explicit viscosity, the equations are equivalent to the Euler equations. This gives:\n",
    "\n",
    "$$\\begin{aligned}\n",
    "  \\frac{\\partial u_x}{\\partial{t}} + \\mathbf{u} \\cdot \\nabla u_x &= - \\frac{1}{\\rho} \\nabla p \n",
    "  \\\\\n",
    "  \\frac{\\partial u_y}{\\partial{t}} + \\mathbf{u} \\cdot \\nabla u_y &= - \\frac{1}{\\rho} \\nabla p + \\eta d\n",
    "  \\\\\n",
    "  \\text{s.t.} \\quad \\nabla \\cdot \\mathbf{u} &= 0,\n",
    "\\end{aligned}$$\n",
    "\n",
    "With an additional transport equation for the passively advected marker density $s$:\n",
    "\n",
    "$$\\begin{aligned}\n",
    "  \\frac{\\partial s}{\\partial{t}} + \\mathbf{u} \\cdot \\nabla s &= 0 \n",
    "\\end{aligned}$$\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "pwmMK-LW_trZ"
   },
   "source": [
    "## Formulation\n",
    "\n",
    "\n",
    "With the notation from {doc}`overview-equations` the inverse problem outlined above can be formulated as a  minimization problem \n",
    "\n",
    "$$\n",
    "\\text{arg min}_{\\mathbf{u}_{0}} \\sum_i \\big( f(x_{t_e,i} ; \\mathbf{u}_{0} )-y^*_{t_e,i} \\big)^2 ,\n",
    "$$\n",
    "\n",
    "where $y^*_{t_e,i}$ are samples of the reference solution at a targeted time $t_e$,\n",
    "and $x_{t_e,i}$ denotes the estimate of our simulator at the same\n",
    "sampling locations and time. \n",
    "The index $i$ here runs over all discretized, spatial degrees of freedom in our fluid solver (we'll have $32\\times40$ below).\n",
    "\n",
    "In contrast to before, we are not dealing with pre-computed quantities anymore, but now $x_{t_e,i}$ is a complex, non-linear function itself.\n",
    "More specifically, the simulator starts with the initial velocity $\\mathbf{u}_0$ and density $s_0$ to compute the $x_{t_e,i}$, by $n$ evaluations of the discretized PDE $\\mathcal{P}$.\n",
    "This gives as simulated final state \n",
    "$y_{t_e,i} = s_{t_e} = \\mathcal{P}^n(\\mathbf{u}_0,s_0)$, where we will leave $s_0$ fixed in the following, and focus on $\\mathbf{u}_0$ as our degrees of freedom.\n",
    "Hence, the optimization can only change $\\mathbf{u}_0$ to align $y_{t_e,i}$ with the references $y^*_{t_e,i}$ as closely as possible.\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "omVCYK5f_tra"
   },
   "source": [
    "## Starting the Implementation\n",
    "\n",
    "First, let's get the loading of python modules out of the way. By importing `phi.torch.flow`, we get fluid simulation functions that work within pytorch graphs and can provide gradients (`phi.tf.flow` would be the alternative for tensorflow).\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "da1uZcDXdVcF",
    "outputId": "66973d88-ec2c-4137-ed5b-1696848be36f"
   },
   "outputs": [],
   "source": [
    "!pip install --upgrade --quiet phiflow==3.1\n",
    "from phi.torch.flow import *  \n",
    "import pylab # for visualizations later on"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "rdSTbMoaS0Uz"
   },
   "source": [
    "## Batched simulations\n",
    "\n",
    "Now we can set up the simulation, which will work in line with the previous \"regular\" simulation example from the {doc}`overview-ns-forw`. However, now we'll directly include an additional dimension, similar to a mini-batch used for NN training. For this, we'll introduce a named dimension called `inflow_loc`. This dimension will exist \"above\" the previous spatial dimensions `y`, `x` which are declared as dimensions for the `vector` channel. As indicated by the name `inflow_loc`, the main differences for this dimension will lie in different locations of the inflow, in order to obtain different flow simulations. The named dimensions in phiflow make it very convenient to broadcast information across matching dimensions in different tensors.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "mphMP0sYIOz-",
    "outputId": "0c3cea02-a1b2-4d88-e756-afbaef0544b0"
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(inflow_locᵇ=4, xˢ=32, yˢ=40)"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# closed domain\n",
    "INFLOW_LOCATION = tensor([(12, 4), (13, 6), (14, 5), (16, 5)], batch('inflow_loc'), channel(vector=\"x,y\"))\n",
    "INFLOW = (1./3.) * CenteredGrid(Sphere(center=INFLOW_LOCATION, radius=3), extrapolation.BOUNDARY, x=32, y=40, bounds=Box(x=(0,32), y=(0,40)))\n",
    "BND = extrapolation.ZERO # closed, boundary conditions for velocity grid below\n",
    "\n",
    "# uncomment this for a slightly different open domain case\n",
    "#INFLOW_LOCATION = tensor([(11, 6), (12, 4), (14, 5), (16, 5)], batch('inflow_loc'), channel(vector=\"x,y\"))\n",
    "#INFLOW = (1./4.) * CenteredGrid(Sphere(center=INFLOW_LOCATION, radius=3), extrapolation.BOUNDARY, x=32, y=40, bounds=Box(x=(0,32), y=(0,40)))\n",
    "#BND = extrapolation.BOUNDARY # open boundaries \n",
    "\n",
    "INFLOW.shape"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "VSisaefX_trh"
   },
   "source": [
    "The last statement verifies that our `INFLOW` grid likewise has an `inflow_loc` dimension in addition to the spatial dimensions `x` and `y`. You can test for the existence of a tensor dimension in phiflow with the `.exists` boolean, which can be evaluated for any dimension name. E.g., above `INFLOW.inflow_loc.exists` will give `True`, while `INFLOW.some_unknown_dim.exists` will give `False`. The $^b$ superscript indicates that `inflow_loc` is a batch dimension.\n",
    "\n",
    "Phiflow tensors are automatically broadcast to new dimensions via their names, and hence typically no-reshaping operations are required. E.g., you can easily add or multiply tensors with differing dimensions. Below we'll multiply a staggered grid with a tensor of ones along the `inflow_loc` dimension to get a staggered velocity that has `x,y,inflow_loc` as dimensions via `StaggeredGrid(...) * math.ones(batch(inflow_loc=4))`."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "SDmFUYlI_tri"
   },
   "source": [
    "We can easily simulate a few steps now starting with these different initial conditions. Thanks to the broadcasting, the exact same code we used for the single forward simulation in the overview chapter will produce four simulations with different smoke inflow positions."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 263
    },
    "id": "2PccI2r5_trj",
    "outputId": "8dc97fa4-6c27-4406-e0c1-cdfb9c95b5e5"
   },
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 720x432 with 4 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "smoke = CenteredGrid(0, extrapolation.BOUNDARY, x=32, y=40, bounds=Box(x=(0,32), y=(0,40)))  # sampled at cell centers\n",
    "velocity = StaggeredGrid(0, BND, x=32, y=40, bounds=Box(x=(0,32), y=(0,40)))  # sampled in staggered form at face centers \n",
    "\n",
    "def step(smoke, velocity):\n",
    "  smoke = advect.mac_cormack(smoke, velocity, dt=1) + INFLOW\n",
    "  buoyancy_force = (smoke * (0, 1)).at(velocity)\n",
    "  velocity = advect.semi_lagrangian(velocity, velocity, dt=1) + buoyancy_force\n",
    "  velocity, _ = fluid.make_incompressible(velocity)\n",
    "  return smoke, velocity\n",
    "\n",
    "for _ in range(20):\n",
    "    smoke,velocity = step(smoke,velocity)\n",
    "\n",
    "# store and show final states (before optimization)\n",
    "smoke_final = smoke \n",
    "fig, axes = pylab.subplots(1, 4, figsize=(10, 6))\n",
    "for i in range(INFLOW.shape.get_size('inflow_loc')):\n",
    "  axes[i].imshow(smoke_final.values.numpy('inflow_loc,y,x')[i,...], origin='lower', cmap='magma')\n",
    "  axes[i].set_title(f\"Inflow {INFLOW_LOCATION.numpy('inflow_loc,vector')[i]}\" + (\", Reference\" if i==3 else \"\"))\n",
    "pylab.tight_layout()\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "V1tfVLqJ_trj"
   },
   "source": [
    "The last image shows the state of the advected smoke fields after 20 simulation steps. The final smoke shape of simulation `[3]` with an inflow at `(16,5)`, with the straight plume on the far right, will be our **reference state** below. The initial velocity of the other three will be modified in the optimization procedure below to match this reference.\n",
    "\n",
    "(As a small side note: phiflow tensors will keep track of their chain of operations using the backend they were created for. E.g. a tensor created with NumPy will keep using NumPy/SciPy operations unless a PyTorch or TensorFlow tensor is also passed to the same operation. Thus, it is a good idea to verify that tensors are using the right backend once in a while, e.g., via `GRID.values.default_backend`.)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "vjIJq_Uz_trk"
   },
   "source": [
    "## Gradients\n",
    "\n",
    "Let's look at how to get gradients from our simulation. The first trivial step taken care of above was to include `phi.torch.flow` to import differentiable operators from which to build our simulator.\n",
    "\n",
    "Now we want to optimize the initial velocities so that all simulations arrive at a final state that is similar to the simulation on the right, where the inflow is located at `(16, 5)`, i.e. centered along `x`.\n",
    "To achieve this, we record the gradients during the simulation and define a simple $L^2$ based loss function. The loss function we'll use is given by $L = | s_{t_e} - s_{t_e}^* |^2$, where $s_{t_e}$ denotes the smoke density, and $s_{t_e}^*$\n",
    "denotes the reference state from the fourth simulation in our batch (both evaluated at the last time step $t_e$).\n",
    "When evaluating the loss function we treat the reference state as an external constant via `field.stop_gradient()`.\n",
    "As outlined at the top, $s$ is a function of $\\mathbf{u}$ (via the advection equation), which in turn is given by the Navier-Stokes equations. Thus, via a chain of multiple time steps $s$ depends in the initial velocity state $\\mathbf{u}_0$.\n",
    "\n",
    "It is important that our initial velocity has the `inflow_loc` dimension before we record the gradients, such that we have the full \"mini-batch\" of four versions of our velocity (three of which will be updated via gradients in our optimization later on). To get the appropriate velocity tensor, we initialize a `StaggeredGrid` with a tensor of zeros along the `inflow_loc` batch dimension. As the staggered grid already has `y,x` and `vector` dimensions, this gives the desired four dimensions, as verified by the print statement below.\n",
    "\n",
    "Phiflow provides a unified API for gradients across different platforms by using functions that need to return a loss values, in addition to optional state values. It uses a loss function based interface, for which we define the `simulate` function below. `simulate` computes the $L^2$ error outlined above and returns the evolved `smoke` and `velocity` states after 20 simulation steps.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "_j7fUGvQ_trl",
    "outputId": "f06dea67-cc48-4af1-a963-46500f90d138"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Velocity dimensions: (inflow_locᵇ=4, xˢ=32, yˢ=40, vectorᶜ=x,y)\n"
     ]
    }
   ],
   "source": [
    "initial_smoke = CenteredGrid(0, extrapolation.BOUNDARY, x=32, y=40, bounds=Box(x=(0,32), y=(0,40)))\n",
    "initial_velocity = StaggeredGrid(math.zeros(batch(inflow_loc=4)), BND, x=32, y=40, bounds=Box(x=(0,32), y=(0,40)))\n",
    "print(\"Velocity dimensions: \"+format(initial_velocity.shape))\n",
    "\n",
    "def simulate(smoke: CenteredGrid, velocity: StaggeredGrid):\n",
    "    for _ in range(20):\n",
    "        smoke,velocity = step(smoke,velocity)\n",
    "        \n",
    "    loss = field.l2_loss(smoke - field.stop_gradient(smoke.inflow_loc[-1]) )\n",
    "    # optionally, use smoother loss with diffusion steps - no difference here, but can be useful for more complex cases\n",
    "    #loss = field.l2_loss(diffuse.explicit(smoke - field.stop_gradient(smoke.inflow_loc[-1]), 1, 1, 10))\n",
    "    \n",
    "    return loss, smoke, velocity\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "pjqeVedM_trm"
   },
   "source": [
    "Phiflow's `field.gradient()` function is the central function to compute gradients. Next, we'll use it to obtain the gradient with respect to the initial velocity. Since the velocity is the second argument of the `simulate()` function, we pass `wrt=[1]`. (Phiflow also has a `field.spatial_gradient` function which instead computes derivatives of tensors along spatial dimensions, like `x,y`.)\n",
    "\n",
    "`gradient` generates a gradient function. As a demonstration, the next cell evaluates the gradient once with the initial states for smoke and velocity. The last statement prints a summary of a part of the resulting gradient tensor.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "grYi0l-g_trn",
    "outputId": "93dae39b-1b31-429a-cf81-f615e23bbf7d"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Some gradient info: StaggeredGrid[(inflow_locᵇ=4, xˢ=32, yˢ=40, vectorᶜ=x,y), size=\u001b[94m(x=32, y=40)\u001b[0m \u001b[93mint64\u001b[0m, extrapolation=\u001b[94m0\u001b[0m]\n",
      "\u001b[92m(xˢ=31, yˢ=40)\u001b[0m \u001b[94m2.61e-08 ± 8.5e-01\u001b[0m \u001b[37m(-2e+01...1e+01)\u001b[0m\n"
     ]
    }
   ],
   "source": [
    "sim_grad = field.gradient(simulate, wrt=[1], get_output=False)\n",
    "(velocity_grad,) = sim_grad(initial_smoke, initial_velocity)\n",
    "\n",
    "print(\"Some gradient info: \" + format(velocity_grad))\n",
    "print(format(velocity_grad.values.inflow_loc[0].vector[0])) # one example, location 0, x component, automatically prints size & content range\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "-drJBAe2_tro"
   },
   "source": [
    "The last two lines just print some information about the resulting gradient field. Naturally, it has the same shape as the velocity itself: it's a staggered grid with four inflow locations. The last line shows how to access the x-components of one of the gradients.\n",
    "\n",
    "We could use this to take a look at the content of the computed gradient with regular plotting functions, e.g., by converting the x component of one of the simulations to a numpy array via `velocity_grad.values.inflow_loc[0].vector[0].numpy('y,x')`. An interactive alternative would be phiflow's `view()` function, which automatically analyzes the grid content and provides UI buttons to choose different viewing modes. You can use them to show arrows, single components of the 2-dimensional velocity vectors, or their magnitudes. Because of its interactive nature, the corresponding image won't show up outside of Jupyter, though, and hence we're showing the vector length below via `plot()` instead.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "id": "2LTHHjtZ_tro"
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<Figure size 864x360 with 5 Axes>"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 864x360 with 5 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "# neat phiflow helper function:\n",
    "v = vis.plot(field.vec_length(velocity_grad)) # show magnitude"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "J7IgFG4o_trp"
   },
   "source": [
    "Not surprisingly, the fourth gradient on the left is zero (it's already matching the reference). The other three gradients have detected variations for the initial round inflow positions shown as positive and negative regions around the circular shape of the inflow. The ones for the larger distances on the left are also noticeably larger."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "3mpyowRYUSS4"
   },
   "source": [
    "\n",
    "\n",
    "## Optimization\n",
    "\n",
    "The gradient visualized above is just the linearized change that points in the direction of an increasing loss. Now we can proceed by updating the initial velocities in the opposite direction to minimize the loss, and iterate to find a minimizer.\n",
    "\n",
    "This is a difficult task: the simulation is producing different dynamics due to the differing initial spatial density configuration. Our optimization should now find a single initial velocity state that gives the same state as the reference simulation at $t=20$. Thus, after 20 non-linear update steps the simulation should reproduce the desired marker density state. It would be much easier to simply change the position of the marker inflow to arrive at this goal, but -- to make things more difficult and interesting here -- the inflow is _not_ a degree of freedom. The optimizer can only change the initial velocity $\\mathbf{u}_0$.\n",
    "\n",
    "The following cell implements a simple steepest gradient descent optimization: it re-evaluates the gradient function, and iterates several times to optimize $\\mathbf{u}_0$ with a learning rate (step size) `LR`.\n",
    "\n",
    "`field.gradient` has a parameter `get_output` that determines whether the original results of the function (`simulate()` in our case) are returned, or only the gradient. As it's interesting to track how the loss evolves over the course of the iterations, let's redefine the gradient function with `get_output=True`. \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "0U8h7_-b_trq",
    "outputId": "11df5469-5c45-41b4-ba21-81114d2a3431"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Optimization step 0, loss: 298.286163\n",
      "Optimization step 1, loss: 291.454376\n",
      "Optimization step 2, loss: 276.057831\n",
      "Optimization step 9, loss: 233.706482\n",
      "Optimization step 19, loss: 232.652145\n",
      "Optimization step 29, loss: 178.186951\n",
      "Optimization step 39, loss: 176.523254\n",
      "Optimization step 49, loss: 169.360931\n",
      "Optimization step 59, loss: 167.578674\n",
      "Optimization step 69, loss: 175.005310\n",
      "Optimization step 79, loss: 169.943680\n"
     ]
    }
   ],
   "source": [
    "sim_grad_wloss = field.gradient(simulate, wrt=[1], get_output=True) # if we need outputs...\n",
    "\n",
    "LR = 1e-03 \n",
    "for optim_step in range(80):    \n",
    "    (loss, _smoke, _velocity), (velocity_grad,) = sim_grad_wloss(initial_smoke, initial_velocity)\n",
    "    initial_velocity = initial_velocity - LR * velocity_grad\n",
    "    if optim_step<3 or optim_step%10==9: print('Optimization step %d, loss: %f' % (optim_step, np.sum(loss.numpy()) ))\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "PI3xY-7m_trr"
   },
   "source": [
    "The loss should have gone down significantly, from almost 300 to below 170, and now we can also visualize the initial velocities that were obtained in the optimization. \n",
    "\n",
    "The following images show the resulting three initial velocities in terms of their x (first set), and y components (second set of images). We're skipping the fourth set with `inflow_loc[0]` because it only contains zeros.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 316
    },
    "id": "FdL_orrX_trr",
    "outputId": "b716256c-9b8a-40d9-fc01-d75e261a728c"
   },
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 720x288 with 6 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "fig, axes = pylab.subplots(1, 3, figsize=(10, 4))\n",
    "for i in range(INFLOW.shape.get_size('inflow_loc')-1):\n",
    "  im = axes[i].imshow(initial_velocity.staggered_tensor().numpy('inflow_loc,y,x,vector')[i,...,0], origin='lower', cmap='magma')\n",
    "  axes[i].set_title(f\"Ini. vel. X {INFLOW_LOCATION.numpy('inflow_loc,vector')[i]}\")\n",
    "  pylab.colorbar(im,ax=axes[i])\n",
    "pylab.tight_layout()\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 318
    },
    "id": "mLhwxsZd_trs",
    "outputId": "5bb43835-6e21-4d97-bb07-17b17215bbc8"
   },
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 720x288 with 6 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "fig, axes = pylab.subplots(1, 3, figsize=(10, 4))\n",
    "for i in range(INFLOW.shape.get_size('inflow_loc')-1):\n",
    "  im = axes[i].imshow(initial_velocity.staggered_tensor().numpy('inflow_loc,y,x,vector')[i,...,1], origin='lower', cmap='magma')\n",
    "  axes[i].set_title(f\"Ini. vel. Y {INFLOW_LOCATION.numpy('inflow_loc,vector')[i]}\")\n",
    "  pylab.colorbar(im,ax=axes[i])\n",
    "pylab.tight_layout()\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "3mitRMPx_trt"
   },
   "source": [
    "## Re-simulation\n",
    "\n",
    "We can also visualize how the full simulation over the course of 20 steps turns out, given the new initial velocity conditions for each of the inflow locations. This is what happened internally at optimization time for every gradient calculation, and what was measured by our loss function. Hence, it's good to get an intuition for which solutions the optimization has found.\n",
    "\n",
    "Below, we re-run the forward simulation with the new initial conditions from `initial_velocity`:\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 263
    },
    "id": "OINe99pf_trt",
    "outputId": "a7c9ade3-3685-40e6-a5f1-97a5084deec9"
   },
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 720x432 with 4 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "smoke = initial_smoke \n",
    "velocity = initial_velocity\n",
    "\n",
    "for _ in range(20):\n",
    "    smoke,velocity = step(smoke,velocity)\n",
    "\n",
    "fig, axes = pylab.subplots(1, 4, figsize=(10, 6))\n",
    "for i in range(INFLOW.shape.get_size('inflow_loc')):\n",
    "  axes[i].imshow(smoke_final.values.numpy('inflow_loc,y,x')[i,...], origin='lower', cmap='magma')\n",
    "  axes[i].set_title(f\"Inflow {INFLOW_LOCATION.numpy('inflow_loc,vector')[i]}\" + (\", Reference\" if i==3 else \"\"))\n",
    "pylab.tight_layout()\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "ootUIrQq_tru"
   },
   "source": [
    "Naturally, the image on the right is the same (this is the reference), and the other three simulations now exhibit a  shift towards the right. As the differences are a bit subtle, let's visualize the difference between the target configuration and the different final states.\n",
    "\n",
    "The following images contain the difference between the evolved simulated and target density. Hence, dark regions indicate where the target should be, but isn't. The top row shows the original states with the initial velocity being zero, while the bottom row shows the versions after the optimization has tuned the initial velocities. Hence, in each column you can compare before (top) and after (bottom): \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 410
    },
    "id": "7lm9Rrel640-",
    "outputId": "6ef7914a-8f63-49af-9a1a-fde1aed37682"
   },
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 720x432 with 12 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "fig, axes = pylab.subplots(2, 3, figsize=(10, 6))\n",
    "for i in range(INFLOW.shape.get_size('inflow_loc')-1):\n",
    "  axes[0,i].imshow(smoke_final.values.numpy('inflow_loc,y,x')[i,...] - smoke_final.values.numpy('inflow_loc,y,x')[3,...], origin='lower', cmap='magma')\n",
    "  axes[0,i].set_title(f\"Org. diff. {INFLOW_LOCATION.numpy('inflow_loc,vector')[i]}\")\n",
    "  pylab.colorbar(im,ax=axes[0,i])\n",
    "for i in range(INFLOW.shape.get_size('inflow_loc')-1):\n",
    "  axes[1,i].imshow(smoke.values.numpy('inflow_loc,y,x')[i,...] - smoke_final.values.numpy('inflow_loc,y,x')[3,...], origin='lower', cmap='magma')\n",
    "  axes[1,i].set_title(f\"Result {INFLOW_LOCATION.numpy('inflow_loc,vector')[i]}\")\n",
    "  pylab.colorbar(im,ax=axes[1,i])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "cuGIjhGx_trw"
   },
   "source": [
    "These difference images clearly show that the optimization managed to align the upper region of the plumes very well. Each original image (at the top) shows a clear misalignment in terms of a black halo, while the states after optimization largely overlap the target smoke configuration of the reference, and exhibit differences closer to zero for the front of each smoke cloud.\n",
    "\n",
    "Note that all three simulations need to \"work\" with a fixed inflow, hence they cannot simply \"produce\" marker density out of the blue to match the target. Also each simulation needs to take into account how the non-linear model equations change the state of the system over the course of 20 time steps. So the optimization goal is quite difficult, and it is not possible to exactly satisfy the constraints to match the reference simulation in this scenario. E.g., this is noticeable at the stems of the smoke plumes, which still show a black halo after the optimization. The optimization was not able to shift the inflow position, and hence needs to focus on aligning the upper regions of the plumes.\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "jHdQureE_trx"
   },
   "source": [
    "## Conclusions\n",
    "\n",
    "This example illustrated how the differentiable physics approach can easily be extended towards significantly more \n",
    "complex PDEs. Above, we've optimized for a mini-batch of 20 steps of a full Navier-Stokes solver. 😄 \n",
    "\n",
    "This is a powerful basis to bring NNs into the picture. Above, the degrees of freedom were still a regular grid, and we've jointly solved a single inverse problem. There were three cases to solve as a mini-batch, of course, but nonetheless the setup still represents a direct _optimization_. Thus, in line with the PINN example of {doc}`physicalloss-code` we've not really dealt with a _machine learning_ task here. However, DP training allows for a range of flexible combinations with NNs that will be the topic of the next chapters.\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "ffaDxZ3x_try"
   },
   "source": [
    "## Next steps\n",
    "\n",
    "Based on the code example above, we can recommend experimenting with the following:\n",
    "\n",
    "- Modify the setup of the simulation to differ more strongly across the four instances, run longer, or use a finer spatial discretization (i.e. larger grid size). Note that this will make the optimization problem tougher, and hence might not converge directly with this simple setup.\n",
    "\n",
    "- As a larger change, add a multi-resolution optimization to handle cases with larger differences. I.e., first solve with a coarse discretization, and then uses this solution as an initial guess for a finer discretization. \n"
   ]
  }
 ],
 "metadata": {
  "colab": {
   "collapsed_sections": [],
   "name": "diffphys-code-ns.ipynb",
   "provenance": []
  },
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
